#include<stdio.h>
#include<stdlib.h>
typedef struct
{
int data;
struct node *next;
}node;

void display(node* start);
int count1(node* start);
void count(node* start);
node* delete(node* start,int n);
int index(node* start,int num);
int pop(node* start,int n);
node* reverse( node* start );  
node* sort( node* start);
node* append(node* start);
node* extend(node* start);      
node* insert(node* start);      

void main()
{
node *start=NULL;
int i=0,n,choice=1;
printf("Enter no. of elements :");
scanf("%d",&n);
        while(i<n)
        {
        node *new_node,*current;
        new_node=(node *)malloc(sizeof(node));
        printf("\n Enter data:");
        scanf("%d",&(new_node->data));
        new_node -> next=NULL;
        if (start==NULL)
                {
                start=new_node;
                current=new_node;
                }
        else
                {
                current->next=new_node;
                current=new_node;
                }
                i++;
        }
        display(start);

while(choice!=0)
{
printf("1.Display list\n");
printf("2.Count list elements\n");
printf("3.Delete element\n");
printf("4.Index of an element\n");
printf("5.Pop element\n");
printf("6.Reverse list\n");
printf("7.Sort list\n");
printf("8.Append element\n");
printf("9.Extend list\n");
printf("10.Insert element\n");
printf("Enter the operation you want to perform (input the number,enter %d to exit):\n",0);
scanf("%d",&choice);

        switch(choice)
        {
        case 0:exit;
        case 1:
                {
                display(start);
                break;}
        case 2:
                {
                count(start);
                display(start);
                break;
                }
        case 3:
                {
                int n;
                printf("Enter the number u want to delete:");
                scanf("%d",&n);
                start=delete(start,n);
                display(start);
                break;
                }
        case 4:
                {
                int i,num;
                printf("Enter the number who's index u want:");
                scanf("%d",&num);
                i=index(start,num);
                if (i==0) printf("The number isn't there in list\n");
                else printf("The number's index is: %d \n",i);
                display(start);
                break;}
        case 5:
                {
                int i,num;
                printf("Enter the position from where u want to pop element:");
                scanf("%d",&i);
		if(i<0 || i>n)
		{
		printf("The number isn't there in list\n");
		}
		else{
                num=pop(start,i);
                printf("The element popped is: %d \n",num);}
                display(start);
                break;}
        case 6:
                {
                start=reverse( start );
                display(start);
                break;}
        case 7:
                {
                sort( start);
                display(start);
                break;}
        case 8:
                {
                append(start);
                display(start);
                break;}
        case 9:
                {
                extend(start);  
                display(start);
                break;}
        case 10:
                {
                insert(start);  
                display(start);
                break;}
        default:
                {
                printf("You entered wrong operation number\n");
                }
        }
}
}

void display(node* start)                               //DISPLAY
{                      
        node *temp;                    
        temp=start;
        printf("The list is :");
        while(temp!=NULL)
        {
                printf("%6d ",temp->data);
                temp=temp->next;
        }
        printf("\n");
}
void count(node* start)                                         //COUNT
{
        int num,i=0,flag=0,sum=0;
        printf("Enter the value : ");
        scanf("%d",&num);
        node* tmp=start;
        while(tmp){
        if(num==(tmp->data)){
        flag=1;
        sum=sum+1;
        tmp = tmp->next;
        }
        else{
        tmp = tmp->next;}
        }
        if(flag==1){
        printf("The count is : %d \n",sum);}
        else{
        printf("Number not in list \n");}
        }

int count1(node * start)                                        
{
node *tempo;                    
        tempo=start;
        int n=0;
        while(tempo!=NULL)
        {
                n++;
                tempo=tempo->next;
        }
return n;
}

node* delete(node* start,int num)                       //DELETE
{
node* lnode = start;
node* pnode = NULL;
while (lnode)
        {
        if(lnode->data==num)
                {
                if(pnode)
                pnode->next=lnode->next;
                else
                start=start->next;	
		break;
                }
        else    pnode = lnode;
       
        lnode=lnode->next;
        }
if (start==NULL){ printf("The list is empty,u should exit now .\n");
                exit(0);
                }
return start;
}

int index(node* start,int num)                          //INDEX
{
int i=1;
node *tmp=start;
while(tmp!=NULL)
{
if (tmp->data==num)
return i;
tmp=tmp->next;
i++;
}
}

int pop(node* start,int n)                              //POP
{
node* tmp=start;
node* prev;
int i;
for(i=1;i<n;i++)
        {
        prev=tmp;
        tmp=tmp->next;
        }
int p=tmp->data;
prev->next=tmp->next;
return p;
}

node* reverse( node* start )                            //REVERSE
{
node *cur,*temp;
cur=NULL;

while(start!=NULL)
{
temp=start;
start=start->next;
temp->next=cur;
cur=temp;
}
return cur;

}
 
node* sort( node* start)                                //SORT
{

int n=count1(start);
int i, j, k, temp ;
    node *p, *q ;

    k = n ;
    for ( i = 0 ; i < n - 1 ; i++)
    {
        p = start ;
        q = p -> next ;

        for ( j = 1 ; j < k ; j++ )
        {
            if ( p -> data > q -> data )
            {
                temp = p -> data ;
                p -> data = q -> data ;
                q -> data = temp ;
            }
            p = p -> next ;
            q = q -> next ;
        }
        k--;
    }  
return start;
}

node* append(node* start)                               //APPEND
{
int num;
printf("Enter the number to be appended:");
scanf("%d",&num);
       node* new=malloc(sizeof(node));        
       new->data=num;
       new->next=NULL;
        node* temp=start;
        while(temp!=NULL)
        {
        if (temp->next==NULL)
        {       temp->next=new;
                break;
        }

        else temp=temp->next;
        }
return start;
}


node* extend(node* start)                               //EXTEND
{
int p,j=0;
node* tmp;
node* s1=NULL;
printf("Enter no. of elements in list to be extended : ");
scanf("%d", &p);
        do
        {
        node *new_node1,*current1;
        new_node1=(node *)malloc(sizeof(node));
        printf("\n Enter data:");
        scanf("%d",&(new_node1->data));
        new_node1 -> next=NULL;
        if (s1==NULL)
                {
                s1=new_node1;
                current1=new_node1;
                }
        else
                {
                current1->next=new_node1;
                current1=new_node1;
                }
                j++;
        } while(j<p);

tmp=start;
while (tmp!=NULL)
{
        if (tmp->next==NULL)
        {
        tmp->next=s1;  
        break;
        }
        else
        tmp=tmp->next;

}
return start;
}

node* insert(node* start)                               //INSERT
{
int i=1,pos,num;
printf("Enter the postion where u want to insert:\n");
scanf("%d",&pos);
printf("Enter the number u want to insert:\n");
scanf("%d",&num);

node* tmp=start;
node* new=malloc(sizeof(node));

while(tmp!=NULL)
{
        if(i==pos)
        {
        new->data=tmp->data;
        new->next=tmp->next;
        tmp->data=num;
        tmp->next=new;
        break;
        }
        else
        {
        tmp=tmp->next;
        i++;    
        }
}
return start;

}